#ifndef ARRAY_BUFFER_H_INC
#define ARRAY_BUFFER_H_INC

#include "ptr_list.h"



class ArrayBuffer: public ListItem {
public:
	static bool  Move(ArrayBuffer* dstBuffer, ArrayBuffer* srcBuffer);
	static uint32_t MoveAsMuch(ArrayBuffer* dstBuffer, ArrayBuffer* srcBuffer);
protected:
	uint32_t	m_typeSize;					
	uint32_t   m_capacity;	
	uint32_t	m_maxCapacity;				
	uint8_t*	m_buffer;
	uint32_t	m_iPeek;				
	uint32_t	m_dataSize;
	uint32_t	m_lostCount;

public:
	ArrayBuffer(uint32_t typeSize, uint32_t initArrayLength, uint32_t maxArrayLength);
	virtual ~ArrayBuffer();

	// 实现ListItem接口
	virtual const char* Name(void) { return(""); }
	
	virtual bool _EnsurePushSpace(uint32_t pushSize);
	virtual void  Reset(void);
	virtual bool  PushInt(long iv);							
	virtual bool  PushFloat(double fv);
	virtual bool  Push(const void* cache, uint32_t cacheCount);
	virtual void  InjectInt(long iv);						
	virtual void  InjectFloat(double fv);
	virtual void  Inject(const void* cache, uint32_t cacheCount);
	virtual uint32_t LostCount(void)			{ return(m_lostCount); }
	virtual bool  PushFrom(ArrayBuffer *pSrcBuffer);			
	virtual uint32_t PushAsMuch(ArrayBuffer* pSrcBuffer);			

	virtual uint32_t TypeSize(void)			{ return(m_typeSize); }
	virtual bool  IsFull(void)				{ return(m_dataSize == m_maxCapacity); }
	virtual uint32_t DataSize(void)			{ return(m_dataSize); }
	virtual uint32_t DataCount(void)			{ return(m_dataSize / m_typeSize); }
	virtual const void* PeekReadArray(void)	{ return(m_buffer + m_iPeek); }
	virtual void  PopAll(void);
	virtual void  Pop(uint32_t outCount);
	virtual uint32_t PopAsMuch(void* dataBuf, uint32_t maxCount);
};


class SyncBuffer : public ArrayBuffer {
protected:
	int		m_delay;					
	int		m_delayCount;			
	
public:
	SyncBuffer(uint32_t typeSize, uint32_t initArrayLength, uint32_t maxArrayLength, int delay);
	virtual ~SyncBuffer() {}

	virtual void  Reset(void);
	virtual void  SetDelay(int delay);
	virtual bool  PushInt(long iv);
	virtual bool  PushFloat(double fv);
	virtual bool  Push(const void* cache, uint32_t cacheCount);
};


class CxTransport {
protected:
	ArrayBuffer*	m_transBuffer;
	CxSection*		m_cs;

public:
	CxTransport(uint32_t typeSize, uint32_t initArrayLength, uint32_t maxArrayLength);
	virtual ~CxTransport();

	virtual void  Reset(void);
	virtual void  Inject(const void* cache, uint32_t cacheCount);
	virtual uint32_t LostCount(void);
	virtual uint32_t MoveFromAsMuch(ArrayBuffer* pSrcBuffer);

	virtual uint32_t MoveToAsMuch(ArrayBuffer* pDstBuffer);
};


class CxDispatcher {
protected:
	uint32_t 		m_typeSize;
	uint32_t 		m_initArrayLength;
	uint32_t 		m_maxArrayLength;
	ObjList* 	m_transBufferList;
	CxSection*	m_cs;

public:
	CxDispatcher(uint32_t typeSize, uint32_t initArrayLength, uint32_t maxArrayLength);
	virtual ~CxDispatcher();


	virtual void  Reset(void);
	virtual void  Inject(const void* cache, uint32_t cacheSize);
	virtual uint32_t TotalLostCount(void);
	virtual uint32_t MoveInAsMuch(ArrayBuffer* pSrcBuffer);


	virtual void* Subscribe(void);
	virtual void  Unsubscribe(void* h);
	virtual uint32_t MoveOutAsMuch(void* h, ArrayBuffer* pDstBuffer);
};

#endif
